package com.becca.cake.core.excel.excelReader.impl;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;

import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.becca.cake.core.excel.excelReader.ExcelUtils;
import com.becca.cake.util.StringUtil;

/**
 * Excel读取
 * @author hejinguo
 * @version $Id: ExcelReaderUtil.java, v 0.1 2014-4-21 下午10:54:07
 */
public class ExcelReaderUtil<T> extends AbsExcelReader<T> {
    private static Log logger = LogFactory.getLog(ExcelReaderUtil.class);

    public ExcelReaderUtil(Class<T> clazz) {
        super(clazz);
    }

    /**
     * 调用方法
     * ExcelReaderUtil excel=new ExcelReaderUtil(entity.class);
     * String  filesName="id,name";
     * Collection cool=excel.readImportExcel(file,filesName,1,0);
     * entity---->对应实体名称
     * filesName---->Excel列和filesName中对应关系.其中filesName为 entity实体对应的属性
     * rowStart--->开始读取的行
     * columnStart---->开始读取的列
     */
    public Collection<T> readImportExcel(InputStream fileUpload, String filesName, int rowStart,
                                         int columnStart) {
        //获取工作薄对象
        Workbook book = super.getWorkBook(fileUpload);
        // 获得第一个工作表对象  
        Sheet sheet = book.getSheet(0);
        //Excel总行数
        int rows = sheet.getRows();
        //Excel总列数
        int columns = sheet.getColumns();
        //读取起始行
        int startRow = ExcelUtils.getStartRow(rowStart);
        //读取起始列
        int startColumn = ExcelUtils.getStartColumn(columnStart);
        //实体对象属性名
        String[] fieldInfo = filesName.split(",");
        //实体属性对象
        Field file;
        Class<? extends Object> c = null;
        Method method = null;
        Collection<T> collection = new ArrayList<T>();
        for (int i = 0, n = rows - startRow; i < n; i++) {//读取行
            boolean isNotEmpty = true;//判断整行数据是否为空
            try {
                //创建实体对象
                T entityT = clazz.newInstance();
                Cell cell = null;
                Object obj = null;
                for (int j = 0, m = columns - startColumn; j < m; j++) {//读取行中的列
                    String filedName = fieldInfo[j];
                    if (StringUtil.isNotEmpty(filedName)) {
                        String methodName = "set" + filedName.substring(0, 1).toUpperCase()
                                            + filedName.substring(1);
                        cell = sheet.getCell(startColumn + j, startRow + i);
                        obj = ExcelUtils.transCellValue(cell);
                        if (isNotEmpty) {
                            if (null != obj) {
                                if (StringUtil.isNotEmpty(obj.toString().trim())) {
                                    isNotEmpty = false;
                                }
                            }
                        }
                        //获取属性对象
                        file = entityT.getClass().getDeclaredField(filedName);
                        c = file.getType();
                        method = entityT.getClass().getMethod(methodName, new Class[] { c });
                        method.invoke(entityT, ExcelUtils.castValue(obj, c));
                    }
                }
                if (!isNotEmpty) {//行不为空
                    collection.add(entityT);
                }
            } catch (SecurityException e) {
                logger.error("安全检查错误!", e);
                throw new SecurityException("安全检查错误!");
            } catch (NoSuchFieldException e) {
                logger.error("实体中没有定义这个属性!", e);
            } catch (IllegalArgumentException e) {
                logger.error("参数类型错误!", e);
                throw new IllegalArgumentException("参数类型错误!");
            } catch (IllegalAccessException e) {
                logger.error("数组越界!", e);
                throw new IllegalArgumentException("数组越界!");
            } catch (InvocationTargetException e) {
                logger.error("在读取Excel文件中的方法出现错误!", e);
            } catch (NoSuchMethodException e) {
                logger.error("在读取Excel文件中的方法出现错误!", e);
            } catch (InstantiationException e) {
                logger.error("", e);
            }
        }
        book.close();
        return collection;
    }

}
